/*
 * Copyright (c) 2020 - present, Inspur Genersoft Co., Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/*
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.inspur.edp.cef.variable.dtgenerator.vardtmGenerate.cmpgenerators;

import com.inspur.edp.bef.component.base.GspComponent;
import com.inspur.edp.cef.designtime.api.operation.CommonOperation;
import com.inspur.edp.cef.generator.DotNetToJavaStringHelper;
import com.inspur.edp.cef.variable.dtgenerator.vardtmGenerate.CompCodeNames;
import com.inspur.edp.cef.variable.dtgenerator.vardtmGenerate.JavaCompCodeNames;
import com.inspur.edp.das.commonmodel.entity.GspCommonModel;
import com.inspur.edp.lcm.metadata.api.entity.GspMetadata;
import com.inspur.edp.lcm.metadata.api.service.MetadataService;
import com.inspur.edp.lcm.metadata.api.service.RefCommonService;
import io.iec.edp.caf.commons.utils.SpringBeanUtils;
import io.iec.edp.caf.runtime.config.BeanUtil;
import org.springframework.util.StringUtils;

/**
 CommonOperation构件生成器基类
 
*/
public abstract class CommonOperationComponentGenerator
{
	/** 
	 UDTDef编号
	 
	*/
	protected String varEntityCode;
	/** 
	 UDTDef程序集名称
	 
	*/
	protected String assemblyName;
	protected String nameSpace;
	/** 
	 原始构件
	 
	*/
	protected GspComponent originalComponent;
	protected String bizObjectID;
	protected GspCommonModel model;
	/** 
	 生成构件元数据
	 
	 @param operation UDT操作
	 @param path 生成指定路径
	 @param varEntityCode UDT编号
	 @param assemblyName UDT程序集名称
	*/
	@Deprecated
	public  String GenerateComponent(GspCommonModel model,CommonOperation operation, String path, String varEntityCode, String assemblyName, String defaultNamespace, String bizObjectID)
	{
		this.varEntityCode = varEntityCode;
		this.assemblyName = assemblyName;
		this.nameSpace = defaultNamespace;
		this.bizObjectID = bizObjectID;
		this.model=model;
		if (DotNetToJavaStringHelper.isNullOrEmpty(operation.getComponentId())) {
			GspMetadata component = createComponent(operation, path);
			//4、建立Action与元数据之间的关联关系
			operation.setComponentId(((GspComponent)component.getContent()).getComponentID());
			//操作的ComponentName用来记录生成的构件元数据的名称
			operation.setComponentName(component.getHeader().getCode());
			return operation.getCode();
		}
		else
		{
			ModifyComponent(operation, path);
		}
		return null;
	}
	/** 
	 新建构件
	 
	 @param operation
	 @param path
	*/
	private GspMetadata createComponent(CommonOperation operation, String path) {
		//1、构建实体
		GspComponent component = BuildComponent();
		//2、赋值
		EvaluateComponentInfo(component, operation, null);
		//3、生成构件
		return EstablishComponent(component, path);
	}

	public GspMetadata createComponent(GspCommonModel model, CommonOperation operation, String path,
			String varEntityCode, String assemblyName, String defaultNamespace, String bizObjectID) {
		if(!StringUtils.isEmpty(operation.getComponentId())) {
			throw new RuntimeException(operation.getCode()+"构件上已存在构件");
		}
		this.varEntityCode = varEntityCode;
		this.assemblyName = assemblyName;
		this.nameSpace = defaultNamespace;
		this.bizObjectID = bizObjectID;
		this.model=model;
		return createComponent(operation, path);
	}
	/** 
	 构造构件实体类
	 
	 @return 
	 构件实体类
	 <see cref="IGSPComponent"/>
	 
	*/
	protected abstract GspComponent BuildComponent();
	/** 
	 为构件赋值
	 
	 @param component 构件实体信息
	 @param operation 动作信息
	*/
	protected abstract void EvaluateComponentInfo(GspComponent component, CommonOperation operation, GspComponent originalComponent);
	/** 
	 生成构件实体对应的构件元数据
	 
	 @param component 构件实体
	 @param path 生成构件元数据指定路径
	 @return 
	 生成的构件元数据名称
	 <see cref="string"/>
	 
	*/
	private GspMetadata EstablishComponent(GspComponent component, String path)
	{
		return DtmMetadataExchangeUtil.getInstance().establishGspMetadata(component, path, this.varEntityCode, this.bizObjectID);
	}

	private RefCommonService refCommonService;
	private RefCommonService getRefCommonService(){
		if(refCommonService == null){
			refCommonService=SpringBeanUtils.getBean(RefCommonService.class);
//			refCommonService = BeanUtil.getAppCtx().getBean(RefCommonService.class);
		}
		return refCommonService;
	}
	/** 
	 修改构件
	 
	 @param operation
	 @param path
	*/
	private void ModifyComponent(CommonOperation operation, String path)
	{
		//1、构建实体
		GspComponent component = BuildComponent();
		String fullPath = "";

		MetadataService metadataService = SpringBeanUtils.getBean(MetadataService.class);
		// 带针对不同类型构件的扩展名的文件全名
		String metadataFileNameWithExtendName = operation.getComponentName()+ JavaCompCodeNames.UDTDtmCmpExtendName;
		if (!metadataService.isMetadataExist(path, metadataFileNameWithExtendName))
		{
			throw new RuntimeException("构件元数据" + metadataFileNameWithExtendName + "不存在！");
		}
		fullPath = path + "\\" + metadataFileNameWithExtendName;
		GspComponent originalComponent = GetOriginalComponent(path, metadataFileNameWithExtendName);
		//2、赋值
		EvaluateComponentInfo(component, operation, originalComponent);
		//4、修改更新构件元数据
		DtmMetadataExchangeUtil.getInstance().UpdateGSPMetadata(component, fullPath, this.varEntityCode, this.bizObjectID);
	}
	/** 
	 获取修改元数据之前的元数据信息
	 
	 @param path
	 @param metadataFileNameWithSuffix
	 @return 
	*/
	private GspComponent GetOriginalComponent(String path, String metadataFileNameWithSuffix)
	{
		MetadataService metadataService = SpringBeanUtils.getBean(MetadataService.class);
		GspMetadata metadata = metadataService.loadMetadata(metadataFileNameWithSuffix, path);
		GspComponent originalComponent = (GspComponent)((metadata.getContent() instanceof GspComponent) ? metadata.getContent() : null);
		return originalComponent;
	}
}
